package kr.co.cherryt.parser.xml;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import kr.co.cherryt.common.CC_Log;
import kr.co.cherryt.common.Utility;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;


public class XmlManager {
	
	public final static int XML_PARSE_COMPLETE = 0x300;
	public final static int UNDEFIND_VALUE = -1;
	
	public static final String DEFAULT_PARSE_MSG = "목록을 불러오는 중입니다";
	
	private ProgressDialog m_loagindDialog = null;
	private Handler m_hSend = null;
	private Object m_objTag = null;
	private int m_nCapaItemArrayCol = 0;
	
	
	//////////////////////////////////////////////////////////////
	// XML 파싱에 사용될 전역 변수 및 상수  
	//////////////////////////////////////////////////////////////
    private String m_szElementName = null;
    private String m_szElementData = null;
   	
	private String ELEMENT_NAME_ITEM_LIST = "channel";
	private String ELEMENT_NAME_ITEM = "item";

    private XmlItem m_xmlItemTemp = null;

    
    public void setNewElementItemList(String szList, String szItem){
    	if(szList != null){
    		ELEMENT_NAME_ITEM_LIST = szList;
    	}

    	if(szItem != null){
    		ELEMENT_NAME_ITEM = szItem;
    	}
    }
    
    
	//////////////////////////////////////////////////////////////
	//xml 파싱에서 사용될 상태 값  
	//////////////////////////////////////////////////////////////
	private static enum xmlElementType{
		XML_ITEM_CHILD_ELEMENT,	/*** item 다음에 오는 유효한 element 인 경우 ***/
		XML_LIST_CHILD_ELEMENT,	/*** item_list or item 다음에 오는 유효한 element 인 경우  ***/
		XML_UNKWON_ELEMENT;		/*** 알 수 없는 element ***/ 
	}

    private xmlElementType m_curXmlType = xmlElementType.XML_UNKWON_ELEMENT;
	
	
	//////////////////////////////////////////////////////////////
	// 서버에 저장된 Item 갯 수를 저장 할 변수  (지울 수 있을것 같은데~~)
	//////////////////////////////////////////////////////////////
	private int m_nServerItemCount = UNDEFIND_VALUE;
	
	
   	////////////////////////////////////////////////
	// XmlManager connection 방식
	////////////////////////////////////////////////
	static public enum connectionType{
		XML_GET, XML_POST, XML_MULTIPART 
	}
	
	connectionType m_connectionType = connectionType.XML_GET;

	
	///////////////////////////////////////////////////////////////////
	// XML Result 처음에 나오는 한개의 XmlItem
	///////////////////////////////////////////////////////////////////
	
	private XmlItem m_arItemListchild = new XmlItem();
	
	////////////////////////////////////////////////////
	// XML Result 처음에 나오는 XmlItem의 배열
	////////////////////////////////////////////////////
	private ArrayList<XmlItem> m_arXmlItem = new ArrayList<XmlItem>();


	/*****************************************************/
	/***************XmlManager 생성자 *****************/
	/*****************************************************/
	
	//////////////////////////////////////////////////////////////////////////////
	// 생성자
	//////////////////////////////////////////////////////////////////////////////
	public XmlManager() {
	}

	public XmlManager(Context context) {
	}

	
	public XmlManager(connectionType type) {

		////////////////////////////////////////////////////////////////////////////
		// POST인지 Get인지를 설정한다.
		////////////////////////////////////////////////////////////////////////////
		m_connectionType = type;
	}

	
	/**
	 * XmlManager에서 사용되는 ArrayList에 대한 Capacity를 설정한다. 미설정 시 elements의 delete, new가 반복 되므로 속도 저하가 발생 될 수 있다.
	 * @param nCol : XML 첫부분에 존재하는 설정 형식의 데이터에 대한 Col 갯 수  
	 * @param nArrayRow : Table 형식의 Xml Data에 대한 Row 갯 수 
	 * @param nArrayCol : Table 형식의 Xml Data에 대한 Col 갯 수 
	 */
	public void setArrayListCapa(int nCol, int nArrayRow, int nArrayCol){

		if(m_arXmlItem != null && nArrayRow> 0){
			m_arXmlItem.ensureCapacity(nArrayRow);
		}
		
		if(m_arItemListchild != null && nCol > 0){
			m_arItemListchild.setArrayCapacity(nCol);
		}
		
		m_nCapaItemArrayCol = nArrayCol;
	}
	
	/*************** getter, setter function *****************/
	private int m_nIntParam = 0;
	
	public void setTag(Object tag){
		m_objTag = tag;
	}

	public Object getTag(){
		return m_objTag;
	}
	
	
	public void setIntParam(int nParam){
		m_nIntParam = nParam;
	}
	
	public int getIntParam(){
		return m_nIntParam;
	}
	
	
	
	
	public ArrayList<XmlItem> getXmlItemArrayList()
	{
		return m_arXmlItem;
	}
	
	
	public XmlItem getXmlItemList(){
		return m_arItemListchild;
	}

	
	
	public int getServerTotalItemCount(){
		return m_nServerItemCount;
	}
	
	////////////////////////////////////////////////
	// XML_POST에서 POST 파라메터를 위해 사용되는 변수
	////////////////////////////////////////////////
	private String m_szPostData = null;
	public void setPostData(String szData){
		m_szPostData = szData;
	}

	////////////////////////////////////////////////
	// XML_MULTIPART에서 파일명 저장을 위해 사용되는 변수
	////////////////////////////////////////////////
	private String m_szFilePath = null;
	public void setFilePath(String szData){
		m_szFilePath = szData;
	}
	
	
	
	
	/***************  XML Parsing !!!!!! *****************/
	private boolean xmlEndElementProcess(XmlPullParser parser){

		// special tag인 경우 상태값 저장
		if(parser.getName().equals(ELEMENT_NAME_ITEM_LIST)){
		
			// item_list가 끝난 이 후의 데이터는 처리 불가!! 
			m_curXmlType = xmlElementType.XML_UNKWON_ELEMENT;
			CC_Log.info("xml", "############## item_list End ####");
			return true;
		}

		else if(parser.getName().equals(ELEMENT_NAME_ITEM)){

			///////////////////////////////////////////////////////
			// item이 끝난 이 후의 데이터는 list_item의 child data!!
			// 만약 item이 다시 시작 되면 다시 item child로 설정 될 것 이므로 문제가 없다!! 
			///////////////////////////////////////////////////////
			m_curXmlType = xmlElementType.XML_LIST_CHILD_ELEMENT;
			
			////////////////////////////////////////////////////////////////////////////
			// item 태그가 끝난 시점에서 child element 정보가 저장된 m_xmlItemTemp를 배열에 추가한다. 
			////////////////////////////////////////////////////////////////////////////
			m_arXmlItem.add(m_xmlItemTemp);

			CC_Log.info("tt3", "!! Show List Start add!!");

			
			CC_Log.info("xml", "############## item End ####");
			return true;
		}
		
		else{

			if(m_curXmlType != xmlElementType.XML_UNKWON_ELEMENT){

				
				if(m_szElementName == null){
					// 기존에 설정된 Element Name이 있어야 한다.
					CC_Log.err("__ xml element is null!!");
					return false;
				}

				
				// 데이터를 저장해야 될 유효한 테그가 시작 되는 거다!!
				
				// add Xml Element new XmlElement
				CC_Log.info("xml", "_________valid item (should add item):" +  m_szElementName);
    		
    			switch(m_curXmlType)
    			{
    				case XML_ITEM_CHILD_ELEMENT:
    					
    					if(m_xmlItemTemp == null){
    						CC_Log.info("xml", "_________error xmlTemp is null");
            				return false;
    					}
    					m_xmlItemTemp.addXmlElement( new XmlElement(m_szElementName, m_szElementData) );
    					break;
    					
    				case XML_LIST_CHILD_ELEMENT:
    					m_arItemListchild.addXmlElement( new XmlElement(m_szElementName, m_szElementData) );
    					break;
    					
    				default:
    					CC_Log.info("xml", "_________error unkown xml type");
        				return false;
    			}
    			
    			m_szElementName = null;
    			m_szElementData = null;
			}
			
		}
		
		return true;
	}
	
	private boolean xmlStartElementProcess(XmlPullParser parser){

		if(parser.getName() == null){
			// Element Name이 null인 경우 에러 처리
			CC_Log.err("_____error____ : XML start element is null");
			return false;
		}
		
		
		// special tag인 경우 상태값 저장
		if(parser.getName().equals(ELEMENT_NAME_ITEM_LIST)){
		
			// item_list가 발견되었음을 저장하고 리턴!! 
			m_curXmlType = xmlElementType.XML_LIST_CHILD_ELEMENT;
			CC_Log.info("xml", "############## item_list Start ####");
			return true;
		}
		else if(parser.getName().equals(ELEMENT_NAME_ITEM)){

			// item이 발견되었음을 저장하고 리턴!! 
			m_curXmlType = xmlElementType.XML_ITEM_CHILD_ELEMENT;
			
			// child로 따라오는 XmlElement를 저장하기 위한 배열 생성, Capacity를 설정하면 처리 속도 증가!!
			m_xmlItemTemp = new XmlItem(m_nCapaItemArrayCol);
			
			CC_Log.info("xml", "############## item Start ####");
			return true;
		}
		else{
		
			if(m_curXmlType != xmlElementType.XML_UNKWON_ELEMENT){
				
				// 데이터를 저장해야 될 유효한 테그가 시작 되는 거다!!
				
				if(m_szElementName != null){
					// 기존에 설정된 Element Name이 없어야 한다!!
					CC_Log.err("__ xml element is not null!!");
					return false;
				}

				// new XmlElement
    			m_szElementName = parser.getName();

    			CC_Log.info("xml", "_________valid item(should create item):" +  m_szElementName);
			}
			
		}		
		return true;
	}
	

	
	////////////////////////////////////////////////////////////////
	// ## xml type A ##
	//<item_list>
	//	<result_code>396825</result_code>
	//</item_list>
	////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////
	// xml 형태가 ## xml type A ## 일때 사용 할 수 있다
	// 암시적으로 item_list의 첫번째 element data를 리턴한다.
	//////////////////////////////////////////////////////
	public String simpleXmlRequest(String szUrl, String szName)
	{
		if(fillItemArray(szUrl)){
		
			if(this.m_arItemListchild.getXmlElementCount() > 0){
			
				if(szName == null){
					return m_arItemListchild.getXmlElement(0).GetData();
				}
				else
				{
					XmlElement element = m_arItemListchild.getXmlElement(szName);
					if(element != null)
						return element.GetData();
				}
			}
		}
		return null;
		
	}

	
	////////////////////////////////////////////////////////////////
	// ## xml type A ##
	//<item_list>
	//	<result_code>396825</result_code>
	//	<aaaaaa>396825</aaaaaa>
	//	<bbbbbb>396825</bbbbbb>
	//</item_list>
	////////////////////////////////////////////////////////////////
	
	//////////////////////////////////////////////////////////
	// xml 형태가 ## xml type A ##, ## xml type B ## 일때 사용 할 수 있다
	// list_item의 하위 elelment 중 원하는 element의 data를 받아온다.
	//////////////////////////////////////////////////////////
	public String simpleXmlRequest(String szUrl)
	{
		return simpleXmlRequest(szUrl, null);
	}
	
	
	/*************** 데이터 삭제 *****************/
	public void clearData(){
		
		m_arItemListchild.clearData();
		m_arXmlItem.clear();
		
	}
	
	
	/*************** Parsing 진입 함수 (동기, 비동기) *****************/

	// 프로그래스바를 띄운다.
	public void showProgressDialog(Context c, String szMessage){
		
		if(szMessage == null){
			szMessage = DEFAULT_PARSE_MSG;
		}

		m_loagindDialog = ProgressDialog.show(c, "", szMessage , true);
		m_loagindDialog.setCancelable(true);
	}
	
	
	// 프로그래스바를 숨긴다.
	public void hiddenProgressDialog(){
		if(m_loagindDialog != null){
			m_loagindDialog.dismiss();
		}
	}


	public boolean fillItemArrayAsync(String szUrl, Handler h, Context context, String szWaitDlgMsg){

		
		////////////////////////////////////////////////////////////////////////////
		// 프로그래스 띄우고 핸들러를 우선 내 객체에서 받은뒤
		// 프로그래스 닫고 전달해주자
		// 나중에 전달하기 위해 m_hSend에 저장 할 뿐 AsyncXmlParserRunable는 h가 사용된다. 
		////////////////////////////////////////////////////////////////////////////
		
		////////////////////////////////////////////////////////////////////////////
		// context는 프로그레스 Dialog를 보여주가 위한 변수다 null인 경우 보여주지 않는 거다
		// szWaitDlgMsg는 프로그레스 Dialog의 Text이며 null인 경우 Default Message를 사용한다.
		////////////////////////////////////////////////////////////////////////////
		if(context != null){
			showProgressDialog(context, szWaitDlgMsg);
		}
		return fillItemArrayAsync(szUrl, h);
		
	}
	
	
	public boolean fillItemArrayAsync(String szUrl, Handler h, Context c){
		
		return fillItemArrayAsync(szUrl, h, c,  null);
	}
	
	
	//onXmlManagerListener
	
	///////////////////////////////////////////////////////////////////////////
	// XML을 이용해서 데이터를  추가한다
	// 파라메터 전송 방식 	: GET
	// szUrl 		 	: 호출 URL
	// h				: 전송 완료 시 호출할 핸들
	///////////////////////////////////////////////////////////////////////////
	public boolean fillItemArrayAsync(String szUrl, Handler h){
		
		m_hSend = h;
		
		AsyncXmlParserRunable aParser = new AsyncXmlParserRunable(szUrl, m_hXmlManager);
		Thread thread = new Thread(aParser);
		thread.setDaemon(true);
		thread.start();
		return true;
	}
	
	
/*	
	public void fillItemArrayAsync(String szUrl){
		fillItemArrayAsync(0, szUrl, null, null);
	}
	
	public void fillItemArrayAsync(String szUrl, Context context){
		fillItemArrayAsync(0, szUrl, context, null);		
	}
	
	public void fillItemArrayAsync(String szUrl, Context context, String szProgressMsg){
		fillItemArrayAsync(0, szUrl, context, szProgressMsg);		
	}
	

	public void fillItemArrayAsync(int nTag, String szUrl){
		fillItemArrayAsync(nTag, szUrl, null, null);		
	}
	
	public void fillItemArrayAsync(int nTag, String szUrl, Context context){
		fillItemArrayAsync(nTag, szUrl, context, null);
	}
	
	public void fillItemArrayAsync(int nTag, String szUrl, Context context, String szProgressMsg){
		m_nResponseTag = nTag;
		AsyncXmlParserRunable aParser = new AsyncXmlParserRunable(szUrl, null);
		Thread thread = new Thread(aParser);
		thread.setDaemon(true);
		thread.start();
	}
*/	
	

	////////////////////////////////////////////////////////////////////////////////
	// XML을 이용해서 데이터를  추가한다. (동기)
	////////////////////////////////////////////////////////////////////////////////
	public boolean fillItemArray(String szUrl)
	{
		
		CC_Log.info("xml", "!! Show List Start__2");

		
		// 문자열 공백 확인
		if(Utility.IsEmpty(szUrl)){
			return false;
		}
		
		try{
    	   // XML 주소 설정
			
        	XmlPullParserFactory parserCreator = XmlPullParserFactory.newInstance();
        	XmlPullParser parser = parserCreator.newPullParser();

			URL url = new URL( szUrl );
			
			if(m_connectionType == connectionType.XML_GET){
	        	parser.setInput( url.openStream(), null );
	        	//parser.setInput( text.openStream(), "euc-kr" );
	        	
			}
			else if(m_connectionType == connectionType.XML_MULTIPART){
				
				// 파라메터는 szUrl에 Get 방식으로 추가하면 된다.
				String szResult = HttpFileUpload(szUrl,  m_szFilePath);
					
				if(szResult == null){
					return false;
				}
				
				StringReader rd = new StringReader(szResult);
				parser.setInput(rd);
			}
			//sooni.jpg
			else{
				
				// FIXME: HttpURLConnection으로 바꾸면 result code도 확인하고 timeout도 설정 할 수 있다.
				URLConnection conn = url.openConnection();
	    	    
	    	    conn.setDoOutput(true);
	    	
	    	    OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
	    	    wr.write(m_szPostData == null ? "" : m_szPostData );
	    	    wr.flush();
	    	    
	    	    BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
	    	    parser.setInput(rd);
			}
    	   
        	int parserEvent = parser.getEventType();
        	
               		
            // XML 전체를 파싱하기 위한 while 문
        	while (parserEvent != XmlPullParser.END_DOCUMENT ){
        		
        		switch(parserEvent){
        			
	        		case XmlPullParser.START_TAG:
	        			CC_Log.info("xml", "START_TAG:"  + parser.getName());
	        			
	        			if(!xmlStartElementProcess(parser)){
	        				return false;
	        			}
	        		break;
	        		case XmlPullParser.TEXT:
	        		case XmlPullParser.CDSECT:
	        			if(m_szElementName != null){
	        				m_szElementData = parser.getText();
	        				CC_Log.info("xml", "XML DATA:"  + m_szElementData);
	        			}
	        				
	        		break;
	        		case XmlPullParser.END_TAG:
	        			if(!xmlEndElementProcess(parser)){
	        				return false;
	        			}
	        			

	        		break;
        		default:
        			CC_Log.info("xml", "unkown event:" + parserEvent);
        		}
        		  
        		parserEvent = parser.next();
        	}
        }catch( Exception e ){
        	
        	// 예외 상황 처리!!
        	CC_Log.info("xml", "Error in xml parsing : " + e);
        }
        
        XmlElement element = m_arItemListchild.getXmlElement("total_cnt");
        
        if(element != null){
        	m_nServerItemCount = Utility.parseInt(element.GetData());
        }
        

        CC_Log.info("xml", "##XML 파싱 끝## TotalCount ::" + m_nServerItemCount);
/*
        if(m_xmlManagerListener != null){
        	m_xmlManagerListener.xmlResponseOk(this);
        }
  */
        
        return true;
	}
	
	
	private String HttpFileUpload(String urlString, String fileName) {


		String lineEnd = "\r\n";
		String boundary = "*****";	
		String twoHyphens = "--";

		String szReturn = null;
		try {
			FileInputStream fileInputStream = null;
			URL connectUrl = null;

			fileInputStream = new FileInputStream(fileName);			
			connectUrl = new URL(urlString);
			Log.d("Test", "mFileInputStream  is " + fileInputStream);
			
			// open connection 
			HttpURLConnection conn = (HttpURLConnection)connectUrl.openConnection();			
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
			
			// write data
			DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
			dos.writeBytes(twoHyphens + boundary + lineEnd);
			dos.writeBytes("Content-Disposition: form-data; name=\"userfile\";filename=\"" + fileName+"\"" + lineEnd);
			dos.writeBytes(lineEnd);
			
			int bytesAvailable = fileInputStream.available();
			int maxBufferSize = 1024;
			int bufferSize = Math.min(bytesAvailable, maxBufferSize);
			
			byte[] buffer = new byte[bufferSize];
			int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
			
			CC_Log.info("image byte is " + bytesRead);
			
			// read image
			while (bytesRead > 0) {
				dos.write(buffer, 0, bufferSize);
				bytesAvailable = fileInputStream.available();
				bufferSize = Math.min(bytesAvailable, maxBufferSize);
				bytesRead = fileInputStream.read(buffer, 0, bufferSize);

				CC_Log.info("read img size: " + bufferSize);
			}	
			
			dos.writeBytes(lineEnd);
			dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
			
			// close streams
			CC_Log.info("File is written");
			fileInputStream.close();
			dos.flush(); // finish upload...			
			
			// get response
			int ch;
			InputStream is = conn.getInputStream();
			StringBuffer b =new StringBuffer();
			while( ( ch = is.read() ) != -1 ){
				b.append( (char)ch );
			}
			szReturn = b.toString(); 

			
			CC_Log.info("result = " + szReturn);
			//mEdityEntry.setText(s);
			
			dos.close();			
			
		} catch (Exception e) {
			Log.d("Test", "exception " + e.getMessage());
			// TODO: handle exception
		}

		return szReturn;
	}	
	
	
	
	
	/********************** XmlElementLink를 위한 함수들!! **********************/

	/////////////////////////////////////////////////////////////////////////////
	// OnXmlManagerListener Listener 
	/////////////////////////////////////////////////////////////////////////////
/*
	OnXmlManagerListener onXmlManagerListener = null; 

	// Allows the user to set an Listener and react to the event
	public void setXmlManagerListener(OnXmlManagerListener listener) {
		onXmlManagerListener = listener;
	}
	
	//Listener 인터페이스 
	public interface OnXmlManagerListener { 	
		public abstract void onShowXmlListViewCell(View v, int position);
		
	}
*/
	
	/////////////////////////////////////////////////////////////////////////////
	// AsyncImageDownloader에서 다운로드과 완료 되면 
	// 메세지를 받아서 처리 할 핸들러
	// Listerner로 구현하게 되면 같은 쓰레드 상에서 ImgeView를 접근하므로 Exception이 발생한다.
	/////////////////////////////////////////////////////////////////////////////
	
	Handler m_hXmlManager = new Handler(){
	
		public void handleMessage(Message msg)
		{
			switch(msg.what)
			{
				case XML_PARSE_COMPLETE:
					//XmlManager.this.notifyDataSetChanged();
					if(m_hSend != null){
						Message msgSend = this.obtainMessage();
						msgSend.what = XML_PARSE_COMPLETE;
						msgSend.obj = XmlManager.this;
						msgSend.arg2 = m_nIntParam;
						m_hSend.sendMessage(msgSend);
						//m_hSend.sendEmptyMessage(XML_PARSE_COMPLETE);
					}
				break;
			}
			return;
		}
	};
	
	/************ Asynchronous XML Parser Runable **************/
	class AsyncXmlParserRunable implements Runnable{
		
		public final static int ASYNC_DOWN_COMPLETE = 0xff01;

		String m_szXmlUrl = null;
		Handler m_hResponse = null;
		
		public AsyncXmlParserRunable(String szUrl, Handler hResponse) {
			m_szXmlUrl = szUrl;
			m_hResponse = hResponse;
		}

		public void run(){
			
			if(m_szXmlUrl != null){
				
				fillItemArray(m_szXmlUrl);
			}
			
			if(m_hResponse != null)
			{
				hiddenProgressDialog();
				m_hResponse.sendEmptyMessage(XML_PARSE_COMPLETE);
			}
			
		}
	}		
	
	
	//////////////////////////////////////////////////////////
	// 리스너
	//////////////////////////////////////////////////////////
/*
	public interface XmlManagerListener {    
    	
    	public abstract void xmlResponseOk(XmlManager xmlMgr);
    	public abstract void xmlResponseErr(XmlManager xmlMgr, int nErrCode, String szErrMessage);
    	public abstract void xmlResponseTimeOut(XmlManager xmlMgr, int nErrCode, String szErrMessage);
    }
    
 */
	
    
	//Listener 변수 
    //XmlManagerListener m_xmlManagerListener = null; 

	// Listener 변수를 저장하는 함수
//	public void setXmlManagerListener(XmlManagerListener listener) {
//		m_xmlManagerListener = listener;
//	}
	
	
	static public class XmlResponse{
		private XmlManager m_xmlManager = null;
		private boolean m_bResultOk = false;
		private int m_nErrCode = 0;
		
		public XmlResponse(Message msg){
			
			if(msg.what == XML_PARSE_COMPLETE){
				XmlManager xmlManager = (XmlManager)msg.obj;
				
				if(xmlManager != null){
					m_xmlManager = xmlManager;
					m_bResultOk = true;
				}
			}
		}
		
		public int getErrCode(){ return m_nErrCode;}
		public XmlManager getXmlManager() {return m_xmlManager;}
		public boolean isResultOk() { return m_bResultOk; }
	}
	
}
